package com.pxxy.mall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.pxxy.common.constant.ProductConstant;
import com.pxxy.common.utils.R;
import com.pxxy.mall.product.dao.AttrAttrgroupRelationDao;
import com.pxxy.mall.product.dao.AttrGroupDao;
import com.pxxy.mall.product.dao.CategoryDao;
import com.pxxy.mall.product.dto.attr.AttrReqDTO;
import com.pxxy.mall.product.entity.*;
import com.pxxy.mall.product.service.ProductAttrValueService;
import com.pxxy.mall.product.vo.AttrResVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pxxy.common.utils.PageUtils;
import com.pxxy.common.utils.Query;

import com.pxxy.mall.product.dao.AttrDao;
import com.pxxy.mall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {


    @Autowired
    private AttrAttrgroupRelationDao relationDao;

    @Autowired
    private AttrGroupDao attrGroupDao;

    @Autowired
    private CategoryDao categoryDao;


    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryAttrPage(Map<String, Object> params, Long catId, String type) {
        LambdaQueryWrapper<AttrEntity> wrapper = getQueryWrapper(params, type);
        if (catId != 0) {
            wrapper.eq(AttrEntity::getCatelogId, catId);
        }
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), wrapper);
        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> records = page.getRecords();
        List<AttrResVo> collect = records.stream().map(t -> {
            AttrResVo attrResVo = new AttrResVo();
            BeanUtils.copyProperties(t, attrResVo);

            //通过attrId找到attrgroupId
            AttrAttrgroupRelationEntity relation = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>()
                    .lambda().eq(AttrAttrgroupRelationEntity::getAttrId, t.getAttrId()));
            //通过分组id找到分组名
            if (relation != null && Objects.nonNull(relation.getAttrGroupId())) {

                AttrGroupEntity attrGroupEntity = attrGroupDao.selectOne(new QueryWrapper<AttrGroupEntity>().lambda()
                        .eq(AttrGroupEntity::getAttrGroupId, relation.getAttrGroupId()));
                attrResVo.setGroupName(attrGroupEntity.getAttrGroupName());
            }
            //获取分类名
            CategoryEntity categoryEntity = categoryDao.selectById(catId);
            if (Objects.nonNull(categoryEntity)) {
                attrResVo.setCatelogName(categoryEntity.getName());
            }
            return attrResVo;
        }).collect(Collectors.toList());
        pageUtils.setList(collect);
        return pageUtils;
    }


    private LambdaQueryWrapper<AttrEntity> getQueryWrapper(Map<String, Object> params, String attrType) {
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            return new QueryWrapper<AttrEntity>().lambda().eq(AttrEntity::getAttrType,
                            "base".equals(attrType) ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode())
                    .and(t -> {
                        t.like(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key);
                    });
        } else {
            return new QueryWrapper<AttrEntity>().lambda().eq(AttrEntity::getAttrType,
                    "base".equals(attrType) ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
        }
    }


    /**
     * 保存attr
     *
     * @param reqDTO
     */
    @Transactional
    @Override
    public void saveAttr(AttrReqDTO reqDTO) {
        //保存基本数据
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(reqDTO, attrEntity);
        this.save(attrEntity);
        //保存关联关系
        if (reqDTO.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            AttrAttrgroupRelationEntity relation = new AttrAttrgroupRelationEntity();
            relation.setAttrId(attrEntity.getAttrId());
            relation.setAttrGroupId(reqDTO.getAttrGroupId());
            relationDao.insert(relation);
        }
    }

    @Override
    public AttrResVo getDetail(Long attrId) {
        AttrResVo attrResVo = new AttrResVo();
        AttrEntity attr = this.getById(attrId);
        if (Objects.nonNull(attr)) {
            //设置attr的所有属性
            BeanUtils.copyProperties(attr, attrResVo);
            List<Long> catelogPath = new ArrayList<>();

            //设置分组路径
            catelogPath = getCatelogPath(attr.getCatelogId(), catelogPath);
            Collections.reverse(catelogPath);
            attrResVo.setCatelogPath(catelogPath.toArray(new Long[catelogPath.size()]));
        }
        //设置AttrGroupId
        AttrAttrgroupRelationEntity relation = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().lambda()
                .eq(AttrAttrgroupRelationEntity::getAttrId, attrId));
        if (Objects.nonNull(relation)) {
            attrResVo.setAttrGroupId(relation.getAttrGroupId());
        }
        return attrResVo;
    }

    private List<Long> getCatelogPath(Long catelogId, List<Long> catelogPath) {
        if (Objects.nonNull(catelogId)) {
            catelogPath.add(catelogId);
            CategoryEntity categoryEntity = categoryDao.selectById(catelogId);
            if (categoryEntity.getParentCid() != 0) {
                getCatelogPath(categoryEntity.getParentCid(), catelogPath);
            }
            return catelogPath;
        }
        return null;
    }

    /**
     * 修改
     *
     * @param reqDTO
     */
    @Transactional
    @Override
    public void updateAttrDetail(AttrReqDTO reqDTO) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(reqDTO, attrEntity);

        this.updateById(attrEntity);

        AttrAttrgroupRelationEntity relation = new AttrAttrgroupRelationEntity();
        relation.setAttrGroupId(reqDTO.getAttrGroupId());
        relation.setAttrId(attrEntity.getAttrId());

        Long count = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().lambda()
                .eq(AttrAttrgroupRelationEntity::getAttrId, relation.getAttrId()));
        if (count > 0) {

            relationDao.update(relation, new UpdateWrapper<AttrAttrgroupRelationEntity>()
                    .lambda()
                    .eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId()));
        } else {
            relationDao.insert(relation);
        }

    }

    /**
     * 获取属性分组没有关联的其他属性
     *
     * @param params
     * @param attrGroupId
     * @return
     */
    @Override
    public PageUtils queryNoattrRelationPage(Map<String, Object> params, Long attrGroupId) {

        //查出当前分组的类
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
        Long catelogId = attrGroupEntity.getCatelogId();

        //通过当前的分类id找到所有所有已分组的属性
        List<AttrGroupEntity> entities = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().lambda().eq(AttrGroupEntity::getCatelogId, catelogId));
        //通过当前类id找到所有的分组
        List<Long> collect = entities.stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toList());
        List<AttrAttrgroupRelationEntity> relationEntities = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                .lambda().in(AttrAttrgroupRelationEntity::getAttrGroupId, collect));
        //通过关联的分组找到关联的属性id
        List<Long> attrIds = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());


        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<AttrEntity>();
        wrapper.eq(AttrEntity::getCatelogId, catelogId).notIn(AttrEntity::getAttrId, attrIds).
                eq(AttrEntity::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.and(t -> t.eq(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key));
        }
        IPage<AttrEntity> page = this.baseMapper.selectPage(new Query<AttrEntity>().getPage(params), wrapper);
        return new PageUtils(page);
    }

    /**
     * 获取spu规格
     */
    @Override
    public R getBaseListforspu(Long spuId) {
        if (Objects.nonNull(spuId)) {

            List<ProductAttrValueEntity> entities = productAttrValueService.getBaseMapper().selectList(new QueryWrapper<ProductAttrValueEntity>()
                    .lambda().eq(ProductAttrValueEntity::getSpuId, spuId));
            return R.ok().put("data", entities);
        } else {
            return null;
        }
    }

    @Transactional
    @Override
    public void updateAttrSpu(List<ProductAttrValueEntity> productAttrValueEntities, Long spuId) {
        if (spuId != null) {
            productAttrValueService.remove(new QueryWrapper<ProductAttrValueEntity>().lambda()
                    .eq(ProductAttrValueEntity::getSpuId, spuId));
            List<ProductAttrValueEntity> collect = productAttrValueEntities.stream().map(t -> {
                ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
                BeanUtils.copyProperties(t, productAttrValueEntity);
                productAttrValueEntity.setSpuId(spuId);
                return productAttrValueEntity;
            }).collect(Collectors.toList());
            productAttrValueService.saveBatch(collect);
        }
    }


    @Transactional
    @Override
    public boolean removeByIds(Collection<?> list) {

        List<Long> ids = new ArrayList<>();
        list.stream().forEach(t -> {
            AttrAttrgroupRelationEntity relation = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().
                    lambda().eq(AttrAttrgroupRelationEntity::getAttrId, t));
            if (relation != null) {
                ids.add(relation.getId());
            }
        });
        if (ids.size() > 0) {
            relationDao.deleteBatchIds(ids);
        }
        return super.removeByIds(list);
    }
}